package com.yanliang.edu.factory;

import com.yanliang.anno.Autowired;
import com.yanliang.anno.Service;
import com.yanliang.edu.utils.TransactionManager;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * 代理工厂
 * @Author : yanliang
 * @Data : 04/12/2020 10:55 PM
 */
@Service(value="proxyFactory")
public class ProxyFactory {

    @Autowired(value = "transactionManager")
    private TransactionManager transactionManager;

    /**
     * 获取代理对象
     * @param targetObj 目标代理对象
     * @return
     */
    public Object getProxy(Object targetObj){
        return Proxy.newProxyInstance(targetObj.getClass().getClassLoader(), targetObj.getClass().getInterfaces(), new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

                Object result = null;
                try {
                    System.out.println("-- 代理执行前增强逻辑 --");
                    transactionManager.beginTransaction();
                    result =  method.invoke(targetObj,args);
                    System.out.println("-- 代理执行后增强逻辑 --");
                    transactionManager.commit();
                    return result;
                } catch (Exception e) {
                    transactionManager.rollback();
                    throw new RuntimeException(e);
                }
            }
        });
    }




    /**
     * 创建CgLib代理
     * @param transactionManager
     * @param thisClass
     * @param originBean
     * @return
     */
    public static Object createCglibProxy(TransactionManager transactionManager, Class thisClass, Object originBean) {
        return Enhancer.create(thisClass, new MethodInterceptor() {
            @Override
            public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
                Object result = null;

                try{
                    // 开启事务(关闭事务的自动提交)
                    transactionManager.beginTransaction();

                    result =method.invoke(originBean,objects);

                    // 提交事务
                    transactionManager.commit();
                }catch (Exception e) {
                    e.printStackTrace();
                    // 回滚事务
                    transactionManager.rollback();
                    // 抛出异常便于上层servlet捕获
                    throw e;

                }
                return result;
            }
        });
    }

    /**
     * 创建JDK代理
     * @param transactionManager
     * @param thisClass
     * @param targetBean
     * @return
     */
    public static Object createJdkProxy(TransactionManager transactionManager, Class thisClass, Object targetBean) {
        return Proxy.newProxyInstance(thisClass.getClassLoader(), thisClass.getInterfaces(), new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                Object result = null;

                try{
                    // 开启事务(关闭事务的自动提交)
                    transactionManager.beginTransaction();

                    result = method.invoke(targetBean,args);

                    // 提交事务

                    transactionManager.commit();
                }catch (Exception e) {
                    e.printStackTrace();
                    // 回滚事务
                    transactionManager.rollback();

                    // 抛出异常便于上层servlet捕获
                    throw e;

                }

                return result;
            }
        });
    }



}
